package spoon.core.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;

import spoon.core.exception.ConnectionException;

@Service
public class HttpServiceImpl implements HttpService {

	@Override
	public HttpURLConnection getUrlConnection(String urlString) {
		URL url;
		HttpURLConnection connection = null;
		try {
			url = new URL(urlString);
			connection = (HttpURLConnection) url.openConnection();
			connection.setDoOutput(true);
		} catch (MalformedURLException e) {
			throw new ConnectionException("URL접속 주소로 변환 할 수 없습니다.", e);
		} catch (IOException e) {
			throw new ConnectionException(e);
		}

		return connection;
	}

	@Override
	public String getSource(String url) {
		HttpURLConnection connection = this.getUrlConnection(url);
		return this.getSource(connection);
	}

	@Override
	public String getSource(String url, String params) {
		HttpURLConnection connection = this.getUrlConnection(url);

		try (OutputStream os = connection.getOutputStream();) {
			os.write(params.getBytes("UTF-8"));
			os.flush();
		} catch (IOException e) {
			throw new ConnectionException(connection.toString(), e);
		}

		return this.getSource(connection);
	}

	@Override
	public String getSource(HttpURLConnection connection) {
		StringBuffer sb = new StringBuffer();
		try (BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));) {
			if (connection.getResponseCode() != 200) {
				return "";
			}

			String line;
			while ((line = in.readLine()) != null) {
				sb.append(line);
			}
		} catch (UnsupportedEncodingException e) {
			throw new ConnectionException("UTF-8로 전환할 수 없습니다.", e);
		} catch (IOException e) {
			throw new ConnectionException(connection.toString(), e);
		}
		return sb.toString();
	}

	@Override
	public Elements getElements(String url, String selector) {
		Document doc = null;
		try {
			doc = Jsoup.connect(url).timeout(10000).get();
		} catch (IOException e) {
			throw new ConnectionException(url + "에 접속할 수 없습니다.", e);
		}
		return doc.select(selector);
	}

	@Override
	public String getJavascript(String src) {
		Document doc = null;

		try {
			doc = Jsoup.connect(src).ignoreContentType(true).get();
		} catch (IOException e) {
			throw new ConnectionException(src + "에 접속할 수 없습니다.", e);
		}

		return doc.html();
	}

}
